#利用JoinableQueue实现生产者与消费者，并且加入了哨兵，来监听生产者的要求
from multiprocessing import JoinableQueue,Process
import time

#参数q为JoinableQueue队列实例
def mark(q):
    #循环接受信息,一直运行，这也下面为什么要将它设为后台进程的原因，必须保证当主线程退出时，它可以退出
    while True:
        value = q.get()
        print(value)  # 实际开发过程中，此处一般用来进行有用的处理
        # 消费者发送信号：任务完成（此处实例的任务就是打印一下下）
        q.task_done()
        #我来方便看出效果，特意停留1s
        time.sleep(1)

        #使用哨兵，监听生产者的消息，此处通过判断value是否为None来判断传递的消息
        if value==None:
            #执行哨兵计划后，后面的语句都不会输出
            break




if __name__=="__main__":
    #实例化JoinableQueue
    q=JoinableQueue()

    #定义消费者进程
    p=Process(target=mark,args=(q,))
    #将消费者线程设置为后台进程，随创建它的进程（此处是主进程）的终止而终止
    #也就是当它的创建进程（此处是主现场）意外退出时，它也会跟随一起退出。
    #并且后台进程无法创建新的进程
    p.daemon=True

    #启动消费者进程
    p.start()

    #模拟生产者，生产多个项
    for xx in range(5):
        print(xx)
        #当xx==3时去执行哨兵计划
        if xx==3:
            print("我用哨兵计划了")
            q.put(None)
            print("哨兵计完美执行")
        q.put("第%d条消息"%xx)


    #等待所有项都处理完成再退出，由于使用了哨兵计划，队列没有完全执行，所以会一直卡在这个位置
    q.join()

    print("程序真正退出了")





